package com.yixing.tech.common.convert;

import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Optional;

public class StringToDateConverter implements Converter<String, Date> {

    private final DateTimeFormatter[] DATE_FORMATTERS = new DateTimeFormatter[]{
            DateTimeFormatter.ofPattern("yyyy-M-d"),
            DateTimeFormatter.ofPattern("yyyy-MM-dd"),
    };

    private final DateTimeFormatter[] DATE_TIME_FORMATTERS = new DateTimeFormatter[]{
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS"),
            DateTimeFormatter.ofPattern("yyyy-M-dd H:mm:ss"),
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSXXX"),
            DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"),
            DateTimeFormatter.ofPattern("yyyy/M/d H:m:s"),
            DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"),
    };

    @Override
    public Date convert(String source) {
        return Optional.ofNullable(source).map(this::tryConvertData).orElse(null);
    }

    @Override
    public Class<String> getSourceType() {
        return String.class;
    }

    @Override
    public Class<Date> getTargetType() {
        return Date.class;
    }

    private Date tryConvertData(String dateStr) {
        if(!StringUtils.hasLength(dateStr)) {
            return null;
        }
        // 匹配日期
        int tryIndex = 0;
        while (tryIndex < DATE_FORMATTERS.length) {
            try {
                return Date.from(LocalDate.parse(dateStr, DATE_FORMATTERS[tryIndex])
                                .atTime(0, 0, 0)
                        .atZone(ZoneOffset.systemDefault()).toInstant());
            } catch (Throwable e) {
                tryIndex += 1;
            }
        }

        // 匹配日期时间
        tryIndex = 0;
        while (tryIndex < DATE_TIME_FORMATTERS.length) {
            try {
                return Date.from(LocalDateTime.parse(dateStr, DATE_TIME_FORMATTERS[tryIndex])
                        .atZone(ZoneOffset.systemDefault()).toInstant());
            } catch (Throwable e) {
                tryIndex += 1;
            }
        }
        return null;
    }

}
